package rexsee.multimedia;

import java.io.File;

import rexsee.core.browser.Browser;
import rexsee.core.browser.RexseeUrl;
import rexsee.core.browser.clazz.ActivityResult.ActivityResultListener;
import rexsee.core.browser.clazz.JavascriptInterface;
import rexsee.core.transportation.RexseeUpload;
import rexsee.core.utilities.Utilities;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;

public class RexseeCamera implements JavascriptInterface {

	public static final String INTERFACE_NAME = "Camera";
	@Override
	public String getInterfaceName() {
		return mBrowser.application.resources.prefix + INTERFACE_NAME;
	}
	@Override
	public JavascriptInterface getInheritInterface(Browser childBrowser) {
		return this;
	}
	@Override
	public JavascriptInterface getNewInterface(Browser childBrowser) {
		return new RexseeCamera(childBrowser);
	}

	public static final String EVENT_ONTAKEPICTURESUCCESSED = "onTakePictureSuccessed";
	public static final String EVENT_ONTAKEPICTUREFAILED = "onTakePictureFailed";
	public static final String EVENT_ONTAKEVIDEOSUCCESSED = "onTakeVideoSuccessed";
	public static final String EVENT_ONTAKEVIDEOFAILED = "onTakeVideoFailed";

	private String mediaFile = null;

	private long mIntentTime = -1;

	private final Browser mBrowser;
	public RexseeCamera(Browser browser) {

		mBrowser = browser;
		browser.eventList.add(EVENT_ONTAKEPICTURESUCCESSED);
		browser.eventList.add(EVENT_ONTAKEPICTUREFAILED);
		browser.eventList.add(EVENT_ONTAKEVIDEOSUCCESSED);
		browser.eventList.add(EVENT_ONTAKEVIDEOFAILED);

	}

	private String contentToPath(String content) {
		ContentResolver contentResolver = mBrowser.getContext().getContentResolver();
		Cursor cursor = contentResolver.query(Uri.parse(content), new String[]{"_data"}, null, null, "_id desc");
		if (cursor == null || cursor.getCount() == 0) return null;
		cursor.moveToFirst();
		File file = new File(cursor.getString(0));
		if (file.exists() && (mIntentTime > 0 && file.lastModified() > mIntentTime)) {
			String rtn = "file://" + cursor.getString(0);
			cursor.close();
			return rtn;
		} else {
			cursor.close();
			return null;
		}
	}
	private boolean isValidResult(String path) {
		File file = new File(Uri.parse(path).getSchemeSpecificPart());
		return (file.exists() && (mIntentTime > 0 && file.lastModified() > mIntentTime)) ? true : false;
	}
	private void returnPic(String output, String path) {
		if (output == null) {
			mediaFile = null;
			mBrowser.eventList.run(EVENT_ONTAKEPICTUREFAILED);
		} else if (output.equals(path)) {
			mediaFile = path;
			mBrowser.eventList.run(EVENT_ONTAKEPICTURESUCCESSED, new String[]{mediaFile});
		} else {
			if (isValidResult(output)) {
				if (Utilities.copy(output, path)) {
					mediaFile = path;
					mBrowser.eventList.run(EVENT_ONTAKEPICTURESUCCESSED, new String[]{mediaFile});
				} else {
					mediaFile = null;
					mBrowser.eventList.run(EVENT_ONTAKEPICTUREFAILED);
				}
			} else {
				mediaFile = null;
				mBrowser.eventList.run(EVENT_ONTAKEPICTUREFAILED);
			}
		}
	}
	private void returnVideo(String output, String path) {
		if (output == null) {
			mediaFile = null;
			mBrowser.eventList.run(EVENT_ONTAKEVIDEOFAILED);
		} else if (output.equals(path)) {
			mediaFile = path;
			mBrowser.eventList.run(EVENT_ONTAKEVIDEOSUCCESSED, new String[]{mediaFile});
		} else {
			if (isValidResult(output)) {
				if (Utilities.copy(output, path)) {
					mediaFile = path;
					mBrowser.eventList.run(EVENT_ONTAKEVIDEOSUCCESSED, new String[]{mediaFile});
				} else {
					mediaFile = null;
					mBrowser.eventList.run(EVENT_ONTAKEVIDEOFAILED);
				}
			} else {
				mediaFile = null;
				mBrowser.eventList.run(EVENT_ONTAKEVIDEOFAILED);
			}
		}
	}

	// JavaScript Interface

	public void takePicture() {
		takePicture(0);
	}
	public void takePicture(int quality) {
		try {
			Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
			intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, (quality == 0) ? 0 : 1);
			mIntentTime = System.currentTimeMillis();
			mBrowser.activityResult.start(intent, new ActivityResultListener() {
				@Override
				public void run(int resultCode, Intent resultIntent) {
					if (resultCode == Activity.RESULT_OK) {
						String output = resultIntent.getDataString();
						if (output == null) {
							output = contentToPath(RexseeUrl.URI_MEDIA_IMAGE);
						} else if (output.toLowerCase().startsWith("file://")) {
						} else if (output.toLowerCase().startsWith("content://")) {
							output = contentToPath(output);
						} else {
							output = contentToPath(RexseeUrl.URI_MEDIA_IMAGE);
						}
						returnPic(output, output);
					} else {
						returnPic(null, null);
					}
				}
			});
		} catch (Exception e) {
			mBrowser.exception(getInterfaceName(), e);
		}
	}
	public void takePicture(int quality, final String path) {
		try {
			Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
			intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, (quality == 0) ? 0 : 1);
			intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.parse(path));
			mIntentTime = System.currentTimeMillis();
			mBrowser.activityResult.start(intent, new ActivityResultListener() {
				@Override
				public void run(int resultCode, Intent resultIntent) {
					if (resultCode == Activity.RESULT_OK) {
						if (isValidResult(path)) {
							returnPic(path, path);
						} else {
							String output = resultIntent.getDataString();
							if (output == null) {
								returnPic(contentToPath(RexseeUrl.URI_MEDIA_IMAGE), path);
							} else if (output.toLowerCase().startsWith("file://")) {
								returnPic(output, path);
							} else if (output.toLowerCase().startsWith("content://")) {
								returnPic(contentToPath(output), path);
							} else {
								returnPic(contentToPath(RexseeUrl.URI_MEDIA_IMAGE), path);
							}
						}
					} else {
						returnPic(null, path);
					}
				}
			});
		} catch (Exception e) {
			mBrowser.exception(getInterfaceName(), e);
		}
	}

	public void takeVideo() {
		takeVideo(0);
	}
	public void takeVideo(int quality) {
		try {
			Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
			intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, (quality == 0) ? 0 : 1);
			mIntentTime = System.currentTimeMillis();
			mBrowser.activityResult.start(intent, new ActivityResultListener() {
				@Override
				public void run(int resultCode, Intent resultIntent) {
					if (resultCode == Activity.RESULT_OK) {
						String output = resultIntent.getDataString();
						if (output == null) {
							output = contentToPath(RexseeUrl.URI_MEDIA_VIDEO);
						} else if (output.toLowerCase().startsWith("file://")) {
						} else if (output.toLowerCase().startsWith("content://")) {
							output = contentToPath(output);
						} else {
							output = contentToPath(RexseeUrl.URI_MEDIA_VIDEO);
						}
						returnVideo(output, output);
					} else {
						returnVideo(null, null);
					}
				}
			});
		} catch (Exception e) {
			mBrowser.exception(getInterfaceName(), e);
		}
	}
	public void takeVideo(int quality, final String path) {
		try {
			Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
			intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, (quality == 0) ? 0 : 1);
			intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.parse(path));
			mIntentTime = System.currentTimeMillis();
			mBrowser.activityResult.start(intent, new ActivityResultListener() {
				@Override
				public void run(int resultCode, Intent resultIntent) {
					if (resultCode == Activity.RESULT_OK) {
						if (isValidResult(path)) {
							returnVideo(path, path);
						} else {
							String output = resultIntent.getDataString();
							if (output == null) {
								returnVideo(contentToPath(RexseeUrl.URI_MEDIA_VIDEO), path);
							} else if (output.toLowerCase().startsWith("file://")) {
								returnVideo(output, path);
							} else if (output.toLowerCase().startsWith("content://")) {
								returnVideo(contentToPath(output), path);
							} else {
								returnVideo(contentToPath(RexseeUrl.URI_MEDIA_VIDEO), path);
							}
						}
					} else {
						returnVideo(null, path);
					}
				}
			});
		} catch (Exception e) {
			mBrowser.exception(getInterfaceName(), e);
		}
	}

	public void prepareUpload() {
		if (mediaFile == null || mediaFile == "") {
			mBrowser.exception(getInterfaceName(), "Picture or video is not ready.");
		} else {
			RexseeUpload uploadObject = (RexseeUpload) mBrowser.interfaceList.get(mBrowser.application.resources.prefix + RexseeUpload.INTERFACE_NAME);
			if (uploadObject == null) {
				mBrowser.exception(getInterfaceName(), "Upload object is not ready.");
			} else {
				uploadObject.selectedFiles.add(mediaFile);
			}
		}
	}

	public void upload(String action, String name) {
		if (mediaFile == null || mediaFile == "") {
			mBrowser.exception(getInterfaceName(), "Picture or video is not ready.");
		} else {
			RexseeUpload uploadObject = (RexseeUpload) mBrowser.interfaceList.get(mBrowser.application.resources.prefix + RexseeUpload.INTERFACE_NAME);
			if (uploadObject == null) {
				mBrowser.exception(getInterfaceName(), "Upload object is not ready.");
			} else {
				uploadObject.clear();
				uploadObject.selectedFiles.add(mediaFile);
				uploadObject.upload(action, name);
			}
		}
	}

}
